
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область ОписаниеПеременных

Перем Типы;
Перем Токены;
Перем Исходник;
Перем ТаблицаТокенов;
Перем ТаблицаОшибок;
Перем ТаблицаЗамен;
Перем Стек;
Перем Счетчики;
Перем Директивы;
Перем Аннотации;
Перем СимволыПрепроцессора;

Перем ИсполнениеНаКлиенте; //Булево
Перем ИменаПеременных;//Массив из Строка
Перем ИсходящиеПеременные;//Массив из Строка

#КонецОбласти

#Область ПрограммныйИнтерфейс

Процедура Открыть(Парсер, Параметры) Экспорт
	
	Типы = Парсер.Типы();
	Токены = Парсер.Токены();
	Исходник = Парсер.Исходник();
	ТаблицаТокенов = Парсер.ТаблицаТокенов();
	ТаблицаОшибок = Парсер.ТаблицаОшибок();
	ТаблицаЗамен = Парсер.ТаблицаЗамен();
	Стек = Парсер.Стек();
	Счетчики = Парсер.Счетчики();
	Директивы = Парсер.Директивы();
	Аннотации = Парсер.Аннотации();
	СимволыПрепроцессора = Парсер.СимволыПрепроцессора();
	
	ИсполнениеНаКлиенте = Параметры.ИсполнениеНаКлиенте;

	ИменаПеременных = Новый Массив;
	Если ТипЗнч(Параметры.ИменаПеременных)	= Тип("Массив") Тогда
		Для Каждого Стр Из Параметры.ИменаПеременных Цикл
			ИменаПеременных.Добавить(Стр);
		КонецЦикла;
	КонецЕсли;
	
	ИсходящиеПеременные = Новый Массив;
	Если ТипЗнч(Параметры.СтруктураМодуля) = Тип("Структура") Тогда
		Если Параметры.СтруктураМодуля.Свойство("Переменные") Тогда
			Для Каждого Стр Из Параметры.СтруктураМодуля.Переменные Цикл
				ИсходящиеПеременные.Добавить(Стр);
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Функция Закрыть() Экспорт
	Возврат Неопределено;
КонецФункции

Функция Подписки() Экспорт
	Подписки = Новый Массив;
	Подписки.Добавить("ПосетитьМодуль");
	Подписки.Добавить("ПосетитьОбъявлениеПеременнойМодуля");
	//Подписки.Добавить("ПосетитьОбъявлениеСпискаПеременныхМодуля");

	Возврат Подписки;
КонецФункции

#Область РеализацияПодписок

Процедура ПосетитьМодуль(ОписаниеМодуля) Экспорт    
	Если ОписаниеМодуля.Операторы.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ПозицияНачала=Неопределено;
   	ОбъявлениеСпискаПеременныхМодуля = Неопределено;

	КоличествоОбъявлений=ОписаниеМодуля.Объявления.Количество();
	Для НомерОбъявления=1 По КоличествоОбъявлений Цикл
		ТекОбъявление=ОписаниеМодуля.Объявления[КоличествоОбъявлений-НомерОбъявления];
		Если ТекОбъявление.Тип=Типы.ИнструкцияПрепроцессораЕсли
			Или ТекОбъявление.Тип=Типы.ИнструкцияПрепроцессораИначеЕсли Тогда
			Продолжить;
		КонецЕсли;      
		Если ТекОбъявление.Тип = Типы.ОбъявлениеСпискаПеременныхМодуля Тогда
			ОбъявлениеСпискаПеременныхМодуля = ТекОбъявление;
			Прервать;
		КонецЕсли;
		
	КонецЦикла;

	Если ОбъявлениеСпискаПеременныхМодуля = Неопределено Тогда
		Если КоличествоОбъявлений > 0 Тогда
			ТекОбъявление = ОписаниеМодуля.Объявления[0];
			ПозицияНачала = ТекОбъявление.Начало.Позиция;
			Если ТекОбъявление.Тип = Типы.ОбъявлениеМетода Тогда
				Если ТекОбъявление.Сигнатура.Директивы.Количество() > 0 Тогда
					ПозицияНачала = ТекОбъявление.Сигнатура.Директивы[0].Начало.Позиция;
				КонецЕсли;
			КонецЕсли;
		Иначе
			Если ОписаниеМодуля.Операторы.Количество() > 0 Тогда
				ПозицияНачала = ОписаниеМодуля.Операторы[0].Начало.Позиция;
			КонецЕсли;
			
		КонецЕсли;
	Иначе
		ПозицияНачала = ОбъявлениеСпискаПеременныхМодуля.Конец.Позиция +ОбъявлениеСпискаПеременныхМодуля.Конец.Длина +1;	
		Если ОбъявлениеСпискаПеременныхМодуля.Директивы.Количество() > 0 Тогда    
			ПоследнияяДиректива = ОбъявлениеСпискаПеременныхМодуля.Директивы[ОбъявлениеСпискаПеременныхМодуля.Директивы.Количество()-1];
			ПозицияНачала = ПоследнияяДиректива.Конец.Позиция + ПоследнияяДиректива.Конец.Длина +1;
		КонецЕсли;
	КонецЕсли;
	
	Если ПозицияНачала=Неопределено Тогда
		Если ОписаниеМодуля.Операторы.Количество() > 0 Тогда
			ПозицияНачала = ОписаниеМодуля.Операторы[0].Начало.Позиция;
		КонецЕсли;
	КонецЕсли;
	
	Если ПозицияНачала=Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Вставка(ТекстПеременныхМодуля()+ТекстВстраиваемыхМетодов(), ПозицияНачала);    
	
	ПозицияНачалаОператоров = ОписаниеМодуля.Операторы[0].Начало.Позиция;
	ТекстНачалаПроцедурыИсполнения = "
	| 
	|"+?(ИсполнениеНаКлиенте,"&НаКлиенте","")+"
    |Функция УИ_ВыполнитьАлгоритм() Экспорт
	|";
	
	Вставка(ТекстНачалаПроцедурыИсполнения, ПозицияНачалаОператоров);       
	
	ПоследнийОператор = ОписаниеМодуля.Операторы[ОписаниеМодуля.Операторы.Количество()-1];
	
	ТекстЗавершенияМетода="
	|___УИ__РезультатВыполненияАлгоритма___ЗначенияПеременных = Новый Структура;";
	Для Каждого ИмяПеременной Из ИсходящиеПеременные Цикл
		ТекстЗавершенияМетода = ТекстЗавершенияМетода
								+ "
								  |___УИ__РезультатВыполненияАлгоритма___ЗначенияПеременных.Вставить("""
								+ ИмяПеременной
								+ """, "
								+ ИмяПеременной
								+ ");";

	КонецЦикла;
	ТекстЗавершенияМетода = ТекстЗавершенияМетода + "
	|Возврат ___УИ__РезультатВыполненияАлгоритма___ЗначенияПеременных;
	|КонецФункции";
	Вставка(ТекстЗавершенияМетода, ПоследнийОператор.Конец.Позиция + ПоследнийОператор.Конец.Длина + 1);
КонецПроцедуры // ПосетитьОператорПрисваивания()

Процедура ПосетитьОбъявлениеПеременнойМодуля(Объявление) Экспорт
	Если Не ИсполнениеНаКлиенте Тогда
		Возврат;
	КонецЕсли;
	Вставка("
	|&НаКлиенте
	|", Объявление.Начало.Позиция - 6);
КонецПроцедуры



//Процедура ПокинутьОператорПрисваивания(ОператорПрисваивания) Экспорт
//
//КонецПроцедуры // ПокинутьОператорПрисваивания()

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Функция ТекстВстраиваемыхМетодов() 
	Текст = "
	|"+?(ИсполнениеНаКлиенте,"&НаКлиенте","")+"
	|Процедура УИ_ИнициализироватьПеременные(УИ_Переменные) Экспорт
	|	Для Каждого КлючЗначение Из УИ_Переменные Цикл
	|		ЭтотОбъект[КлючЗначение.Ключ] = КлючЗначение.Значение;
	|	КонецЦикла;
	|КонецПроцедуры
	|";
	
	
	Возврат Текст+ Символы.ПС;
КонецФункции

Функция ТекстПеременныхМодуля()
	КодДляВставки = "";

	Для Каждого ТекПеременная Из ИменаПеременных Цикл
		КодДляВставки = КодДляВставки + "
										|" + ?(ИсполнениеНаКлиенте, "&НаКлиенте", "") + "
																						|Перем " + ТекПеременная+" Экспорт;";
	КонецЦикла;

	Возврат КодДляВставки+ Символы.ПС;
КонецФункции

Процедура Ошибка(Текст, Начало, Конец = Неопределено, ЕстьЗамена = Ложь)
	Ошибка = ТаблицаОшибок.Добавить();
	Ошибка.Источник = "ИмяЭтогоПлагина";
	Ошибка.Текст = Текст;
	Ошибка.ПозицияНачала = Начало.Позиция;
	Ошибка.НомерСтрокиНачала = Начало.НомерСтроки;
	Ошибка.НомерКолонкиНачала = Начало.НомерКолонки;
	Если Конец = Неопределено Или Конец = Начало Тогда
		Ошибка.ПозицияКонца = Начало.Позиция + Начало.Длина;
		Ошибка.НомерСтрокиКонца = Начало.НомерСтроки;
		Ошибка.НомерКолонкиКонца = Начало.НомерКолонки + Начало.Длина;
	Иначе
		Ошибка.ПозицияКонца = Конец.Позиция + Конец.Длина;
		Ошибка.НомерСтрокиКонца = Конец.НомерСтроки;
		Ошибка.НомерКолонкиКонца = Конец.НомерКолонки + Конец.Длина;
	КонецЕсли;
	Ошибка.ЕстьЗамена = ЕстьЗамена;
КонецПроцедуры

Процедура Замена(Текст, Начало, Конец = Неопределено)
	НоваяЗамена = ТаблицаЗамен.Добавить();
	НоваяЗамена.Источник = "ИмяЭтогоПлагина";
	НоваяЗамена.Текст = Текст;
	НоваяЗамена.Позиция = Начало.Позиция;
	Если Конец = Неопределено Тогда
		НоваяЗамена.Длина = Начало.Длина;
	Иначе
		НоваяЗамена.Длина = Конец.Позиция + Конец.Длина - Начало.Позиция;
	КонецЕсли;
КонецПроцедуры

Процедура Вставка(Текст, Позиция)
	НоваяЗамена = ТаблицаЗамен.Добавить();
	НоваяЗамена.Источник = "ИмяЭтогоПлагина";
	НоваяЗамена.Текст = Текст;
	НоваяЗамена.Позиция = Позиция;
	НоваяЗамена.Длина = 0;
КонецПроцедуры
#КонецОбласти


#КонецЕсли








